//
//  YKFragmentView.swift
//  YKSwiftViews
//
//  Created by edward on 2023/10/25.
//  Copyright © 2023 Edward（本内容遵循MIT协议）. All rights reserved.
//

import UIKit

public class YKFragmentView: UIView {
    
    private let yk_fragment_sub_cell_key = "yk_fragment_sub_cell_key"
    
    public weak var delegate:YKFragmentViewDelegate? {
        didSet {
            
            ui()
        }
    }
    
    public override var frame: CGRect {
        didSet {
            super.frame = frame
            
            ui()
        }
    }
    
    private lazy var headerView:YKFragmentHeaderView = {
        let headerView = YKFragmentHeaderView.init(frame: .init(x: 0, y: 0, width: 0, height: 0), delegate: self)
        
        return headerView
    }()
    
    private var subViews:[YKFragmentSubViewDelegate] = []
    
    private lazy var collectionView:UICollectionView = {
        let layout = UICollectionViewFlowLayout()
        layout.scrollDirection = .horizontal
        let collectionView = UICollectionView(frame: .zero, collectionViewLayout: layout)
        
        collectionView.delegate = self
        collectionView.dataSource = self
        
        collectionView.isPagingEnabled = true
        collectionView.showsHorizontalScrollIndicator = false
        collectionView.showsVerticalScrollIndicator = false
        
        collectionView.bounces = false
        
        collectionView.alwaysBounceVertical = false
        collectionView.alwaysBounceHorizontal = false
        
        collectionView.register(UICollectionViewCell.classForCoder(), forCellWithReuseIdentifier: yk_fragment_sub_cell_key)
        
        return collectionView
    }()
    
    public override init(frame: CGRect) {
        super.init(frame: frame)
        
        ui()
    }

    public convenience init(frame:CGRect, delegate:YKFragmentViewDelegate? = nil) {
        self.init(frame: frame)
        
        self.delegate = delegate
        
        DispatchQueue.main.async {
            
            if let index = self.delegate?.fragmentViewFirstLoadShowIndex?(self) {
                self.headerView.scroll(index)
            } else {
                self.headerView.scroll(0)
            }
            
        }
    }
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
}

private extension YKFragmentView {
    
    func ui() {
        
        for view in self.subviews {
            view.removeFromSuperview()
        }
        
        self.addSubview(self.headerView)
        self.addSubview(self.collectionView)
        
        self.reset()
    }
    
    func reset() {
        
        if let subViews = delegate?.fragmentViewSetUpSubDelegate(self) {
            self.subViews = subViews
        }
        
        delegate?.fragmentViewResetViewLayout(self, header: self.headerView, bottom: self.collectionView)
        
        self.reload()
        
    }
}

public extension YKFragmentView {
    
    func reload() {
        
        self.headerView.reload()
        
        self.collectionView.reloadData()
    }
}

extension YKFragmentView: YKFragmentHeaderViewDelegate {
    
    func sizeOfItem(_ indexPath: IndexPath) -> CGSize {
        if indexPath.row < self.subViews.count {
            let subDelegate = self.subViews[indexPath.row]
            if let size = subDelegate.fragmentSubViewSizeOfHeaderItem?() {
                return size
            } else if let size = self.delegate?.fragmentView?(self, sizeOfHeaderItemAt: indexPath) {
                return size
            } else {
                return .init(width: self.bounds.size.width / CGFloat(self.subViews.count), height: self.headerView.bounds.size.height)
            }
        }  else {
            return .zero
        }
    }
    
    func numberOfItem() -> Int {
        return self.subViews.count
    }
    
    func setupSubView(_ indexPath: IndexPath, itemView: UIView, isSelect: Bool) -> UIView {
        if indexPath.row < self.subViews.count {
            let subDelegate = self.subViews[indexPath.row]
            if let view = subDelegate.fragmentSubViewViewForHeader?(itemView, isSelect) {
                return view
            } else if let view = self.delegate?.fragmentView?(self, viewForHeaderAt: indexPath, itemView, isSelect) {
                return view
            } else {
                return UIView.init()
            }
        }  else {
            return UIView.init()
        }
        
        return UIView.init()
    }
    
    func didSelet(with indexPath: IndexPath) {
        self.collectionView.scrollToItem(at: indexPath, at: .left, animated: true)
    }
    
    func headerViewScrollDidAnimated() -> Bool {
        
        if let animated = self.delegate?.fragmentViewHeaderScrollDidAnimated?(self) {
            return animated
        } else {
            return true
        }
    }
    
    func viewDidAppear(_ index: Int) {
        
        if index < self.subViews.count {
            let subDelegate = self.subViews[index]
            subDelegate.fragmentSubViewViewDidAppear?()
        }
    }
    
    func viewDidDisappear(_ index: Int) {
        if index < self.subViews.count {
            let subDelegate = self.subViews[index]
            subDelegate.fragmentSubViewViewDidDisappear?()
        }
    }
}

extension YKFragmentView: UICollectionViewDelegateFlowLayout, UICollectionViewDataSource {
    
    public func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return self.subViews.count
    }
    
    public func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: yk_fragment_sub_cell_key, for: indexPath)
        
        let delegate = self.subViews[indexPath.row]
        
        let view = delegate.fragmentSubViewSetupMainView()
        view.frame = self.bounds
        
        for view in cell.contentView.subviews {
            view.removeFromSuperview()
        }
        cell.contentView.addSubview(view)
        
        return cell
    }
    
    public func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
        
        return collectionView.bounds.size
    }
    
    public func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumLineSpacingForSectionAt section: Int) -> CGFloat {
        return 0
    }
    
    public func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumInteritemSpacingForSectionAt section: Int) -> CGFloat {
        return 0
    }
    
    public func scrollViewDidEndScrollingAnimation(_ scrollView: UIScrollView) {
        
        let currentIndex = Int(scrollView.contentOffset.x / scrollView.bounds.size.width)
        self.headerView.scroll(currentIndex)
        
    }
    
    public func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {
        let currentIndex = Int(scrollView.contentOffset.x / scrollView.bounds.size.width)
        self.headerView.scroll(currentIndex)
        
    }
}
